<?php
//-------------------------------------------------------------------------
// OVIDENTIA http://www.ovidentia.org
// Ovidentia is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
// USA.
//-------------------------------------------------------------------------
/**
 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
 * @copyright Copyright (c) 2006 by CANTICO ({@link http://www.cantico.fr})
 */
include_once 'base.php';

require_once $GLOBALS['babInstallPath'] . '/utilit/dateTime.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/widget.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/color.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/label.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/frame.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/hboxlayout.class.php';
require_once $GLOBALS['babInstallPath'] . '/addons/widgets/widgets/vboxlayout.class.php';




/**
 * Constructs a Widget_FullCalendar.
 *
 * @param string $id			The item unique id.
 * @return Widget_FullCalendar
 */
function Widget_FullCalendar($id = null)
{
	return new Widget_FullCalendar($id);
}



/**
 *
 */
class Widget_FullCalendar extends Widget_Widget implements Widget_Displayable_Interface
{
	const VIEW_MONTH = 'month';
	const VIEW_WEEK = 'agendaWeek';
	const VIEW_WORKWEEK = 'agendaWorkWeek';
	const VIEW_DAY = 'agendaDay';

	/**
	 * The calendar periods
	 * @var array	of Widget_CalendarPeriod
	 */
	private $_periods = array();

	/**
	 * The day that should be displayed by the calendar.
	 * @var BAB_DateTime
	 */
	private $_date;

	/**
	 * The first day of the week (0-6) displayed in a week view.
	 * @var int
	 */
	private $_firstDayOfWeek = 0;


	/**
	 * The time format
	 * @var string
	 */
	private $timeFormat = null;


	private $gcalFeeds = array();


	public function __construct($id = null)
	{
		parent::__construct($id);
		$this->setTimeFormat('%R{-%R}');
	}

	/**
	 * Sets the type of view that should be displayed by the calendar.
	 *
	 * @param string $view		One of Widget_FullCalendar::VIEW_*
	 * @return Widget_FullCalendar
	 */
	public function setView($view)
	{
		 $this->view = $view;
		 $this->setMetadata('view', $view);
		 return $this;
	}



	/**
	 * Returns the view that should be displayed by the calendar.
	 *
	 * @return string
	 */
	public function getView()
	{
		if (!isset($this->view)) {
			$this->setView(self::VIEW_WEEK);
		}
		return $this->view;
	}



	/**
	 * Sets the format of time.
	 *
	 * Only usage of the following is allowed:
	 *  %H  Two digit representation of the hour in 24-hour format  00 through 23
	 *  %I 	Two digit representation of the hour in 12-hour format 	01 through 12
	 *  %l (lower-case 'L') 	Hour in 12-hour format, with a space preceeding single digits 	1 through 12
	 *  %M 	Two digit representation of the minute 	00 through 59
	 *  %p 	UPPER-CASE 'AM' or 'PM' based on the given time 	Example: AM for 00:31, PM for 22:23
	 *  %P 	lower-case 'am' or 'pm' based on the given time 	Example: am for 00:31, pm for 22:23
	 *  %r 	Same as "%I:%M:%S %p" 	Example: 09:34:17 PM for 21:34:17
	 *  %R 	Same as "%H:%M" 	Example: 00:35 for 12:35 AM, 16:44 for 4:44 PM
	 *  %S 	Two digit representation of the second 	00 through 59
	 *  %T 	Same as "%H:%M:%S" 	Example: 21:34:17 for 09:34:17 PM
	 *  %X 	Preferred time representation based on locale, without the date 	Example: 03:59:16 or 15:59:16
	 *
	 * @param string $format	The format string as described in the php strftime function.
	 * @return Widget_FullCalendar
	 */
	public function setTimeFormat($format)
	{
		assert('is_string($format); /* The "format" parameter must be a string */');
		$this->timeFormat = $format;
		$s = array('%H', '%I', '%l', '%M', '%p', '%P', '%r', '%R', '%S', '%T', '%X');
		$t = array('HH', 'hh', 'h', 'mm', 'TT', 'tt', 'hh:mm:ss TT', 'HH:mm', 'ss', 'HH:mm:ss', 'HH:mm:ss');
		$fcTimeFormat = str_replace($s, $t, $format);
		$this->setMetadata('timeFormat', $fcTimeFormat);
		return $this;
	}

	/**
	 * Returns the format of the date.
	 *
	 * @return string
	 */
	public function getTimeFormat()
	{
		return $this->timeFormat;
	}




	/**
	 * Sets the day that should be displayed by the calendar.
	 *
	 * @param BAB_DateTime $startDate
	 * @return Widget_FullCalendar
	 */
	public function setDate(BAB_DateTime $startDate)
	{
		$this->_date = $startDate;
		$this->setMetadata('year', $startDate->getYear());
		$this->setMetadata('month', $startDate->getMonth());
		$this->setMetadata('date', $startDate->getDayOfMonth());
		return $this;
	}



	/**
	 * Returns the day that should be displayed by the calendar.
	 *
	 * @return BAB_DateTime
	 */
	public function getDate()
	{
		if (!isset($this->_date)) {
			$this->setDate(BAB_DateTime::now());
		}
		return $this->_date;
	}



	/**
	 * Sets the first day of the week (0-6) displayed in a week view.
	 *
	 * @param int $startDayOfWeek	a number in [0-6] or null to unset.
	 * @return Widget_FullCalendar
	 */
	public function setFirstDayOfWeek($firstDayOfWeek)
	{
		assert('is_null($firstDayOfWeek) || (is_numeric($firstDayOfWeek) && (int)$firstDayOfWeek >= 0 && (int)$firstDayOfWeek < 7); /* The "firstDayOfWeek" parameter must be a numeric value between 0 and 6 or null. */');
		$this->_firstDayOfWeek = $firstDayOfWeek;
		$this->setMetadata('firstDayOfWeek', $firstDayOfWeek);
		return $this;
	}



	/**
	 * Returns the first day of the week (0-6) displayed in the week view.
	 *
	 * @return int		or null
	 */
	public function getFirstDayOfWeek()
	{
		return $this->_firstDayOfWeek;
	}





	/**
	 * Adds a period to the calendar.
	 *
	 * @param Widget_CalendarPeriod $period
	 * @return Widget_FullCalendar
	 */
	function addPeriod(Widget_CalendarPeriod $period)
	{
		$this->_periods[] = $period;
		return $this;
	}



	/**
	 * Creates a new period.
	 *
	 * @param BAB_DateTime $startDate
	 * @param BAB_DateTime $endDate
	 * @return Widget_CalendarPeriod
	 */
	function createPeriod($startDate, $endDate)
	{
		return new Widget_CalendarPeriod($this, $startDate, $endDate);
	}


	public function onDoubleClick(widget_Action $action)
	{
		$this->onDoubleClick = $action;
		$this->setMetadata('doubleClick', $action->url());
	}


	public function onPeriodDoubleClick(widget_Action $action)
	{
		$this->onPeriodDoubleClick = $action;
		$this->setMetadata('periodDoubleClick', $action->url());
	}


	public function onPeriodMoved(widget_Action $action)
	{
		$this->onPeriodMoved = $action;
		$this->setMetadata('periodMoved', $action->url());
	}

	public function onViewDisplayed(widget_Action $action)
	{
		$this->onViewDisplayed = $action;
		$this->setMetadata('viewDisplayed', $action->url());
	}

	/**
	 *
	 * @param widget_Action $action
	 *
	 * @return Widget_FullCalendar
	 */
	public function fetchPeriods(widget_Action $action)
	{
		$this->fetchPeriodsAction = $action;
		$this->setMetadata('fetchPeriods', $action->url());
		return $this;
	}


	public function addGcalFeed($url)
	{
		$this->gcalFeeds[] = $url;
		return $this;
	}

	public function getClasses()
	{
		$classes = parent::getClasses();
		$classes[] = 'widget-fullcalendar';
		return $classes;
	}


	/**
	 * (non-PHPdoc)
	 * @see programs/widgets/Widget_Displayable_Interface#display($canvas)
	 */
	public function display(Widget_Canvas $canvas)
	{
		if (!empty($this->gcalFeeds)) {
			$this->setMetadata('gcalFeeds', $this->gcalFeeds);
		}
		$calendarDiv = $canvas->div($this->getId(), $this->getClasses(), array(), $this->getCanvasOptions());
		$calendarDiv .= $canvas->metadata($this->getId(), $this->getMetadata());
		return $calendarDiv;
	}

}

